package com.isb.emailclient.controller;

import java.io.IOException;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;

import android.app.ProgressDialog;
import android.util.Log;

import com.isb.emailclient.model.SimpleMail;

public abstract class Mail extends Authenticator implements IMail {

	private static final String TAG = Mail.class.getSimpleName();
	private String mailhost; // = "smtp.gmail.com";
	private String pophost; // = "pop.gmail.com";
	private String email;
	private String password;
	private Session session;
	private Folder inbox;

	
	
	static {
		Security.addProvider(new JSSEProvider());
	}

	public Mail() {

	}

	@Override
	public void configMail(String email, String password) {
		this.email = email;
		this.password = password;

		Properties props = new Properties();
		props.setProperty("mail.transport.protocol", "smtp");
		props.setProperty("mail.host", mailhost);
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.socketFactory.fallback", "false");
		props.setProperty("mail.smtp.quitwait", "false");

		session = Session.getInstance(props, this);
	}

	@Override
	public boolean checkLoginInfo() {
		Properties props = System.getProperties();
		props.setProperty("mail.store.protocol", "imaps");

		try {
			Session _session = Session.getDefaultInstance(props, null);
			Store store = _session.getStore("imaps");
			store.connect(this.mailhost, this.email, this.password);

			// get folder list
			Folder[] folders = store.getDefaultFolder().list();

			int i = 0;
			for (i = 0; i < folders.length; i++)
				Log.i(TAG, i + " to read " + folders[i].getName() + " folder");
			return true;
		} catch (AuthenticationFailedException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public List<SimpleMail> getMailList(String nameFolderFilter) {

		List<SimpleMail> mailList = new ArrayList<SimpleMail>();

		Properties props = System.getProperties();
		props.setProperty("mail.store.protocol", "imaps");

		try {
			Session session = Session.getDefaultInstance(props, null);
			Store store = session.getStore("imaps");
			store.connect(this.mailhost, this.email, this.password);

			Folder inbox = store.getFolder(nameFolderFilter);
			inbox.open(Folder.READ_WRITE);
			Message[] messages = inbox.getMessages();

			for (Message msg : messages) {
				msg.getSubject();
				msg.getReceivedDate();
				if (null != msg.getSubject()) {
					Log.i(TAG, (String) msg.getSubject());
				}

				StringBuilder builder = new StringBuilder();

				Object content = msg.getContent();
				if (content instanceof Multipart) {
					Multipart mp = (Multipart) content;
					for (int i = 0; i < mp.getCount(); ++i) {
						try {
							BodyPart bp = mp.getBodyPart(i);
							builder.append((String) bp.getContent());
							builder.append("\n");
						} catch (ClassCastException e) {
							e.printStackTrace();
						}

					}
				}

				SimpleMail mail = new SimpleMail("", new ArrayList<String>(),
						msg.getSubject(), builder.toString());
			}

			return mailList;
		} catch (AuthenticationFailedException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	@Override
	public List<String> getFolderList() {

		List<String> folderList = new ArrayList<String>();

		Properties props = System.getProperties();
		props.setProperty("mail.store.protocol", "imaps");

		try {
			Session _session = Session.getDefaultInstance(props, null);
			Store store = _session.getStore("imaps");
			store.connect(this.mailhost, this.email, this.password);

			// get folder list
			Folder[] folders = store.getDefaultFolder().list();

			int i = 0;
			for (i = 0; i < folders.length; i++)
				folderList.add(folders[i].getFullName());
			// Log.i(TAG, i + " to read " + folders[i].getName() + " folder");
			// return true;
		} catch (AuthenticationFailedException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		// return null;

		return folderList;
	}

	@Override
	public void cacheMail(SimpleMail mail) {

	}

	@Override
	public boolean sendMail(SimpleMail mail) {
		try {
			MimeMessage message = new MimeMessage(session);
			DataHandler handler = new DataHandler(new ByteArrayDataSource(mail
					.getBody().getBytes(), "text/plain"));
			message.setSender(new InternetAddress(mail.getSender()));
			message.setSubject(mail.getSubject());
			message.setDataHandler(handler);
			if (mail.parseToRecipients().indexOf(',') > 0)
				message.setRecipients(Message.RecipientType.TO,
						InternetAddress.parse(mail.parseToRecipients()));
			else
				message.setRecipient(Message.RecipientType.TO,
						new InternetAddress(mail.parseToRecipients()));
			Transport.send(message);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(this.email, this.password);
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getHost() {
		return this.mailhost;
	}

	public void setHost(String mailhost) {
		this.mailhost = mailhost;
	}

	public String getPopHost() {
		return this.pophost;
	}

	public void setPopHost(String pophost) {
		this.pophost = pophost;
	}

}
